/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.refunite.mobile.s60.util;

import java.security.SecureRandom;
import org.refunite.mobile.s60.persistence.PersistenceStoreProvider;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

/**
 *
 * @author I040022
 */
public class SecurityUtility {

    private byte[] AESKey;
    private byte[] AESInitV;

    public SecurityUtility() {
        // try to get key and initV from recordStore
        AESKey = PersistenceStoreProvider.getKey();
        AESInitV = PersistenceStoreProvider.getInitV();
        if (AESKey == null || AESInitV == null) {
            generateKey();
        }
    }

    private void generateKey() {
        SecureRandom sr = new SecureRandom();
        AESKey = new byte[16];
        sr.nextBytes(AESKey);
        AESInitV = new byte[16];
        sr.nextBytes(AESInitV);
        PersistenceStoreProvider.saveKey(AESKey);
        PersistenceStoreProvider.saveInitV(AESInitV);
    }

    public byte[] encryptString(byte[] content) {
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
        // If initV is not given, the program will assume all zeros
        ParametersWithIV piv = new ParametersWithIV((new KeyParameter(AESKey)), AESInitV);
        cipher.init(true, piv);
        byte[] result = new byte[cipher.getOutputSize(content.length)];

        int len = cipher.processBytes(content, 0, content.length, result, 0);

        try {
            cipher.doFinal(result, len);
        } catch (CryptoException ce) {
            ce.printStackTrace();
        }

        return result;

    }

    public byte[] decryptString(byte[] content) {
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
        ParametersWithIV piv = new ParametersWithIV((new KeyParameter(AESKey)), AESInitV);

        cipher.init(false, piv);

        byte[] result = new byte[cipher.getOutputSize(content.length)];

        int len = cipher.processBytes(content, 0, content.length, result, 0);

        try {
            cipher.doFinal(result, len);
        } catch (CryptoException ce) {
            ce.printStackTrace();
        }

        return result;

    }
}
